package com.zlsy.thread.deadlock;

import java.util.Random;

/**
 * @author zhouliang
 * @date 2020/5/13 15:52
 * <p>
 * 哲学家就餐
 */
public class DiningPhilosophers {

    public static class Philosopher implements Runnable {

        private final Object leftChopsticks;
        private final Object rightChopsticks;

        public Philosopher(Object leftChopsticks, Object rightChopsticks) {
            this.leftChopsticks = leftChopsticks;
            this.rightChopsticks = rightChopsticks;
        }

        @Override
        public void run() {
            try {
                while (true) {
                    doAction("Thinking");
                    synchronized (leftChopsticks) {
                        doAction("Picked up left Chopsticks");
                        synchronized (rightChopsticks) {
                            doAction("Picked up right Chopsticks - eating");
                            doAction("Put down right Chopsticks");
                        }
                        doAction("Put down left Chopsticks");
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static void doAction(String action) throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + "" + action);
        Thread.sleep(Integer.valueOf(new Random().nextInt(10)).longValue());
    }

    public static void main(String[] args) {
        Philosopher[] philosophers = new Philosopher[5];
        Object[] chopsticks = new Object[philosophers.length];
        for (int i = 0; i < chopsticks.length; i++) {
            chopsticks[i] = new Object();
        }
        for (int i = 0; i < philosophers.length; i++) {
            Object leftChopsticks = chopsticks[i];
            Object rightChopsticks = chopsticks[(i + 1) % chopsticks.length];
            //拿到筷子
            philosophers[i] = new Philosopher(leftChopsticks, rightChopsticks);
            Thread thread = new Thread(philosophers[i], "哲學家" + (i + 1) + "号");
            thread.start();
        }
    }
}
